package calao.util;

import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;

/** Utility methods for strings.
 * 
 * @author <a href="mailto:nifa@signal25.com">Nicolas Faivre</a>
 *
 */
public class Strings {

	public static String NEWLINE = System.getProperty("line.separator");
	
	static MessageDigest digester;

	static {
		try {
			digester = MessageDigest.getInstance("MD5");
		}
		catch (Exception e) {
			throw new RuntimeException(e);
		}
	}

	private static final char[] HEX = {
		'0', '1', '2', '3', '4', '5', '6', '7',
		'8', '9', 'A', 'B', 'C', 'D', 'E', 'F'
	}; 

	private static final String UTF8 = "UTF-8";

	/** Gets the UTF-8 encoding of a string.
	 */
	public static byte[] toUTF8(String str) {
		try {
			return str.getBytes(UTF8);
		}
		catch (UnsupportedEncodingException e) {
			throw new RuntimeException(e);
		}
	}

	/** Gets a string from its UTF-8 encoding.
	 */
	public static String fromUTF8(byte[] bytes) {
		try {
			return new String(bytes, UTF8);
		}
		catch (UnsupportedEncodingException e) {
			throw new RuntimeException(e);
		}
	}

	/** Gets a string from its UTF-8 encoding.
	 */
	public static String fromUTF8(byte[] bytes, int offset, int length) {
		try {
			return new String(bytes, offset, length, UTF8);
		}
		catch (UnsupportedEncodingException e) {
			throw new RuntimeException(e);
		}
	}

	/** Encodes a string as a CGI parameter value.
	 */
	public static String toCGI(String str) {
		try {
			return java.net.URLEncoder.encode(str, UTF8);
		}
		catch (UnsupportedEncodingException e) {
			throw new RuntimeException(e);
		}
	}

	/** Appends an hexadecimal representation of an array of bytes to a string buffer.
	 */
	public static void appendHexString(StringBuffer buffer, 
			byte[] bytes, int offset, int length, String separator) 
	{
		for (int i=0; i<length; i++) {
			if (i!=0 && separator!=null) buffer.append(separator);
			int b = bytes[offset+i] & 0xFF;
			buffer.append(HEX[b/16]);
			buffer.append(HEX[b%16]);
		}		
	}

	/** Gets an hexadecimal representation of an array of bytes.
	 */
	public static String toHexString(byte[] bytes) {
		StringBuffer buffer = new StringBuffer();
		appendHexString(buffer, bytes, 0, bytes.length, null);
		return buffer.toString();
	}

	/** Signs a string.
	 */
	public static String sign(String string, String secret) {
		return toHexString(digester.digest((string+secret).getBytes()));
	}
	
	/** Computes a MD5 hash.
	 */
	public static String md5Hash(String string) {
		return toHexString(digester.digest(string.getBytes()));
	}

	/** Generates an alphanumeric random string.
	 * The generated string contains digits and alphabetic characters. 
	 */
	public static String random(int length) {
		StringBuffer result = new StringBuffer();
		for (int i=0; i<length; i++) {			
			double randc;
			if (Math.random()<0.3) {
				int range = '9' - '0';
				randc = Math.random() * range + '0';
			}
			else {
				int range = 'z' - 'a';
				randc = Math.random() * range + 'a';
			}
			result.append((char)Math.rint(randc));
		}
		return result.toString();		
	}
	
}
